﻿using Castle.Aop.AspectsHub;
using Castle.Aop.Service;
using Castle.DynamicProxy;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;

namespace Castle.Aop.InjectionHub
{
    public static class InjectionSetup
    {
        private static readonly ProxyGenerator _generator = new ProxyGenerator();

        /// <summary>
        /// 添加依赖注入相关的配置,即：IOC
        /// </summary>
        /// <param name="services"></param>
        /// <returns></returns>
        public static void AddInjection(this IServiceCollection services)
        {
            // 定义依赖接口与生命周期的映射关系
            Dictionary<Type, ServiceLifetime> lifeTimeMap = new Dictionary<Type, ServiceLifetime>
            {
                { typeof(ITransientDependency), ServiceLifetime.Transient},
                { typeof(IScopedDependency),ServiceLifetime.Scoped},
                { typeof(ISingletonDependency),ServiceLifetime.Singleton}
            };

            // 遍历所有程序集中的类
            GlobalAssemblies.AllTypes.ForEach(type =>
            {
                #region
                //// 遍历依赖接口与生命周期的映射关系
                //foreach (var (dependency, lifetime) in lifeTimeMap)
                //{
                //    // 检查当前类是否实现了依赖接口，并且不是抽象类且是类
                //    if (dependency.IsAssignableFrom(type) && dependency != type && !type.IsAbstract && type.IsClass)
                //    {
                //        // 注入实现类
                //        services.Add(new ServiceDescriptor(type, type, lifetime));

                //        // 获取当前类实现的所有接口（排除依赖接口）
                //        var interfaces = GlobalAssemblies.AllTypes
                //            .Where(x => x.IsAssignableFrom(type) && x.IsInterface && x != dependency)
                //            .ToList();

                //        // 如果当前类实现了其他接口
                //        if (interfaces.Any())
                //        {
                //            // 遍历所有接口并注入
                //            foreach (var @interface in interfaces)
                //            {
                //                // 注入AOP代理
                //                services.Add(new ServiceDescriptor(@interface, serviceProvider =>
                //                {
                //                    // 创建拦截器
                //                    var castleInterceptor = new CastleInterceptor();
                //                    // 创建代理实例  CreateInterfaceProxyWithTarget第二个参数是object类型，不是type类型，也就是类的实例，所以从IServiceProvider中获取实例
                //                    return _generator.CreateInterfaceProxyWithTarget(@interface, serviceProvider.GetService(type), castleInterceptor);
                //                }, lifetime));
                //            }
                //        }
                //        // 如果当前类没有实现其他接口，则直接注入自身
                //        else
                //        {
                //            // 注入AOP代理
                //            services.Add(new ServiceDescriptor(type, serviceProvider =>
                //            {
                //                // 创建拦截器
                //                var castleInterceptor = new CastleInterceptor();
                //                // 创建代理实例  CreateClassProxy 只能拦截类中的 virtual 方法，确保目标类中的方法标记为 virtual
                //                return _generator.CreateClassProxy(type, castleInterceptor);
                //            }, lifetime));
                //        }
                //    }
                //}
                #endregion

                // 遍历依赖接口与生命周期的映射关系  
                //foreach (var (dependency, lifetime) in lifeTimeMap)
                //{
                //    // 检查当前类是否实现了依赖接口，并且不是抽象类且是类  
                //    if (dependency.IsAssignableFrom(type) && dependency != type && !type.IsAbstract && type.IsClass)
                //    {
                //        // 注入实现类  
                //        services.Add(new ServiceDescriptor(type, type, lifetime));

                //        // 获取当前类实现的所有接口（排除依赖接口）  
                //        var interfaces = GlobalAssemblies.AllTypes
                //            .Where(x => x.IsAssignableFrom(type) && x.IsInterface && x != dependency)
                //            .ToList();

                //        // 注入所有接口的代理  
                //        foreach (var @interface in interfaces)
                //        {
                //            services.AddProxyService(@interface, type, lifetime);
                //        }

                //        // 如果当前类没有实现其他接口，则直接注入自身的AOP代理  
                //        if (!interfaces.Any())
                //        {
                //            services.AddProxyService(type, type, lifetime, false);
                //        }
                //    }
                //}


                foreach (var (dependency, lifetime) in lifeTimeMap)
                {
                    // 检查当前类是否实现了依赖接口，并且不是抽象类且是类  
                    if (dependency.IsAssignableFrom(type) && dependency != type && !type.IsAbstract && type.IsClass)
                    {
                        // 注入实现类  
                        services.Add(new ServiceDescriptor(type, type, lifetime));

                        // 获取当前类实现的所有接口（排除依赖接口）  
                        var interfaces = GlobalAssemblies.AllTypes
                            .Where(x => x.IsAssignableFrom(type) && x.IsInterface && x != dependency)
                            .ToList();

                        var hasInterfaces = interfaces.Any();
                        var serviceTypes = hasInterfaces ? interfaces.Cast<Type>().ToList() : new List<Type> { type };

                        foreach (var serviceType in serviceTypes)
                        {
                            services.AddProxyService(serviceType, type, lifetime, hasInterfaces);
                        }
                    }
                }
            });
        }

        /// <summary>
        /// 添加代理服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="serviceType"></param>
        /// <param name="implementationType"></param>
        /// <param name="lifetime"></param>
        /// <param name="isInterface"></param>
        private static void AddProxyService(this IServiceCollection services, Type serviceType, Type implementationType, ServiceLifetime lifetime, bool isInterface = true)
        {
            //services.Add(new ServiceDescriptor(serviceType, serviceProvider =>
            //{
            //    CastleInterceptor castleInterceptor = new CastleInterceptor();
            //    if (isInterface)
            //    {
            //        var service = serviceProvider.GetService(implementationType);
            //        // 使用了接口代理（CreateInterfaceProxyWithTarget），这意味着目标类必须实现一个或多个接口
            //        // 创建代理实例  CreateInterfaceProxyWithTarget第二个参数是object类型，不是type类型，也就是类的实例，所以从IServiceProvider中获取实例
            //        return _generator.CreateInterfaceProxyWithTarget(serviceType, service, castleInterceptor);
            //    }
            //    else
            //    {
            //        // CreateClassProxy 只能拦截类中的 virtual 方法，确保目标类中的方法标记为 virtual
            //        return _generator.CreateClassProxy(implementationType, castleInterceptor);
            //    }
            //}, lifetime));
            services.Add(new ServiceDescriptor(serviceType, serviceProvider =>
            {
                var castleInterceptor = new CastleInterceptor(serviceProvider);
                if (isInterface)
                {
                    // 创建接口代理实例
                    var target = serviceProvider.GetService(implementationType);
                    return _generator.CreateInterfaceProxyWithTarget(serviceType, target, castleInterceptor);
                }
                else
                {
                    // 创建类代理实例 - 处理构造函数参数
                    var constructorArgs = GetConstructorArguments(serviceProvider, implementationType);
                    return _generator.CreateClassProxy(implementationType, constructorArgs, castleInterceptor);
                }
            }, lifetime));
        }

        /// <summary>
        /// 创建接口代理实例
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <param name="serviceType"></param>
        /// <param name="implementationType"></param>
        /// <param name="castleInterceptor"></param>
        /// <returns></returns>
        private static object CreateInterfaceProxy(IServiceProvider serviceProvider,
                                                   Type serviceType,
                                                   Type implementationType,
                                                   CastleInterceptor castleInterceptor)
        {
            var targetInstance = serviceProvider.GetRequiredService(implementationType);
            return _generator.CreateInterfaceProxyWithTarget(
                serviceType,
                targetInstance,
                castleInterceptor);
        }

        /// <summary>
        /// 获取构造函数参数
        /// </summary>
        /// <param name="serviceProvider">服务提供者</param>
        /// <param name="type">要实例化的类型</param>
        /// <returns>构造函数参数数组</returns>
        private static object[] GetConstructorArguments(IServiceProvider serviceProvider, Type type)
        {
            // 获取第一个公共构造函数（你可以根据需要调整这个逻辑）
            var constructor = type.GetConstructors().FirstOrDefault();
            if (constructor == null)
            {
                return Array.Empty<object>();
            }

            // 获取构造函数参数并尝试从DI容器解析
            return constructor.GetParameters()
                .Select(p => serviceProvider.GetService(p.ParameterType) ??
                            (p.HasDefaultValue ? p.DefaultValue :
                            throw new InvalidOperationException($"无法解析类型 {type.Name} 的构造函数参数 {p.ParameterType.Name}")))
                .ToArray();
        }

    }
}
